﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data;
using Wheeler.Common.Extensions;
using Wheeler.Domain;
using Wheeler.Web.ViewModels;
using Wheeler.Web.Utility;
using AutoMapper;
using Wheeler.Web.ViewModels.UtilityModels;
using System.Text;
using Wheeler.Common.Xml;
using System.IO;
using System.Drawing;
using Wheeler.Common.DB;

namespace Wheeler.Web.Areas.Private.Controllers
{
    [Authorize(Roles = "Operator,Admin")]
    public class TestResultController : BaseController
    {
		private WheelerEntities _Context = new WheelerEntities();
        
		#region Constructors
		public TestResultController()
		{
		}

		public TestResultController(UserViewModel currentUser)
			: base(currentUser)
        {
        }
		#endregion Constructors

		#region Action Methods
        public ActionResult Index()
        {
            return View("List", BuildTestResultListConfig());
        }

		public ActionResult List()
        {
            return View(BuildTestResultListConfig());
        }

		/// <summary>
        /// Gets a TestResult from Database to edit
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult Edit(int vehicleID, int id = 0, String IsSaved = null)
        {
            TestResult entity = GetTestResult(id, vehicleID);
            if (entity != null && !UserInfo.CanEditTestResult(entity.HasConfirmed, entity.HasPublished))
            {
                return RedirectToAction(String.Format("Confirm/{0}", entity.ID), new { VehicleID = entity.VehicleID });
            }
            TestResultViewModel viewModel = Mapper.Map<TestResult, TestResultViewModel>(entity);
            List<ViewModels.ZGL.Category.ProductGroupProperty> onlyProperties = new List<ViewModels.ZGL.Category.ProductGroupProperty>();
            GetDynamicUI(viewModel, null, onlyProperties);

            if (String.Compare(IsSaved, "true", true) == 0)
                ViewData[AppConstants.ViewDataKeys.SAVED] = true;

            ViewData[AppConstants.ViewDataKeys.GENERIC_KEY] = onlyProperties;
			return View(viewModel);
        }        

		/// <summary>
        /// Saves TestResult Information into the Database
        /// </summary>
        /// <param name="viewModel"></param>
        /// <returns></returns>
		[HttpPost]
		public ActionResult Edit(TestResultViewModel viewModel)
        {
            //if (!ModelState.IsValid)
            //    return View(viewModel);
            if (_Context.IsDuplicateSerialNumber(viewModel.SerialNumber, viewModel.ID))
            {
                TestResult fallbackEntity = GetTestResult(viewModel.ID, viewModel.VehicleID);
                viewModel.ZGL = Mapper.Map<ZGL, ZGLViewModel>(fallbackEntity.ZGL);
                //fallbackEntity.ZGLID = viewModel.ZGLID;
                StringBuilder dProperties = new StringBuilder();
                SetDynamicProperties(fallbackEntity, ref dProperties);
                //viewModel.DynamicProperties = fallbackEntity.DynamicProperties;
                
                List<ViewModels.ZGL.Category.ProductGroupProperty> onlyProperties = new List<ViewModels.ZGL.Category.ProductGroupProperty>();
                GetDynamicUI(viewModel, fallbackEntity.DynamicProperties, onlyProperties);
                ModelState.AddModelError("SerialNumber", "The Serial Number already exists, please use another.");
                ViewData[AppConstants.ViewDataKeys.GENERIC_KEY] = onlyProperties;
                return View(viewModel);
            }
            TestResult entity = GetTestResult(viewModel.ID, viewModel.VehicleID, false);
            bool hasConfirmed = false;
            
            if (viewModel.ID == 0)
                _Context.AddToTestResults(entity);            
            else
                hasConfirmed = entity.HasConfirmed;

            entity = Mapper.Map<TestResultViewModel, TestResult>(viewModel, entity);

            if (viewModel.ID == 0)
            {
                entity.CreatedOn = DateTime.Now;
                entity.CreatedBy = LoggedInUser.ID;
                //entity.TestPerformedOn = DateTime.Now;
                entity.TestRound = GenerateTestRound(entity.VehicleID);
                //UtilityDAO dao = new UtilityDAO();
                //entity.SerialNumber = dao.NextTestResultSerial(entity.VehicleID);
            }
            entity.ModifiedOn = DateTime.Now;
            entity.ModifiedBy = LoggedInUser.ID;
            entity.HasConfirmed = hasConfirmed;
            entity.HasPublished = false;

            //Save Dynamic Properties
            StringBuilder dynamicProperties = new StringBuilder();
            SetDynamicProperties(entity, ref dynamicProperties);

            ///Evaluate Test Result
            ///TODO: No Need to evaluate the test result. So uncommenting this implementation. 
            ///The default test status would be PASSED.
            ///As this database will only contain successful test results.
            //ZGL zgl = _Context.ZGLs.FirstOrDefault(P => P.ID == ConfigReader.DefaultZGLID);
            //Vehicle vehicle = _Context.Vehicles.FirstOrDefault(P => P.ID == viewModel.VehicleID);
            //viewModel.Vehicle = Mapper.Map<Vehicle, VehicleViewModel>(vehicle);
            //viewModel.ZGL = Mapper.Map<ZGL, ZGLViewModel>(zgl);
            ////Set the propertiest
            //GetDynamicUI(viewModel, null);
            //DbObject.TestStatus testStatus = WebUtil.EvaluateTestResult(viewModel);
            //entity.TestStatus = (int)testStatus;

            ///Only Successfull Test Results will be entered here.
            entity.TestStatus = (int)DbObject.TestStatus.PASSED;

            _Context.SaveChanges();            
			//return RedirectToAction(String.Format("Edit/{0}", entity.ID), new {VehicleID = entity.VehicleID, IsSaved = "true" });
            return RedirectToAction(String.Format("Confirm/{0}", entity.ID), new { VehicleID = entity.VehicleID, IsSaved = "true" });
        }

        /// <summary>
        /// Displayes the test restul confirmation dialog
        /// </summary>
        /// <param name="vehicleID"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult Confirm(int vehicleID, int id=0)
        {
            if (vehicleID > 0 && id <= 0)
            {
                TestResult test = _Context.TestResults.FirstOrDefault(P => P.VehicleID == vehicleID);
                if (test != null)
                    return RedirectToAction(String.Format("Confirm/{0}", test.ID), new { VehicleID = vehicleID });
            }
            TestResult entity = GetTestResult(id, vehicleID, true);
            TestResultViewModel viewModel = Mapper.Map<TestResult, TestResultViewModel>(entity);
            List<ViewModels.ZGL.Category.ProductGroupProperty> onlyProperties = new List<ViewModels.ZGL.Category.ProductGroupProperty>();
            GetDynamicUI(viewModel, null, onlyProperties);

            //if (String.Compare(IsSaved, "true", true) == 0)
            //    ViewData[AppConstants.ViewDataKeys.SAVED] = true;

            ViewData[AppConstants.ViewDataKeys.GENERIC_KEY] = onlyProperties;

            //GetDynamicUI(viewModel, null);
            return View(viewModel);
        }

        [HttpPost]
        public ActionResult Confirm(TestResultViewModel viewModel)
        {
            TestResult entity = GetTestResult(viewModel.ID, viewModel.VehicleID, false);
            entity.HasConfirmed = true;
            entity.ModifiedBy = LoggedInUser.ID;
            entity.ModifiedOn = DateTime.Now;
            _Context.SaveChanges();
            return RedirectToAction(String.Format("ConfirmSuccess/{0}", entity.ID), new { VehicleID = entity.VehicleID, IsSaved = "true" });
        }

        /// <summary>
        /// Shows a Confirmation message for the test result at the last step
        /// </summary>
        /// <param name="vehicleID"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult ConfirmSuccess(int vehicleID, int id)
        {
            TestResult entity = GetTestResult(id, vehicleID, true);
            TestResultViewModel viewModel = Mapper.Map<TestResult, TestResultViewModel>(entity);
            return View(viewModel);
        }

        public ActionResult Search(String registrationNo = null, String fromDate = null, String toDate = null, String viewType = null, int pageNo = 0)
        {
            viewType = viewType.IsEmpty() ? ConfigReader.DefaultViewForSearchResults : viewType;

            TestResultSearchModel searchModel = new TestResultSearchModel(registrationNo.UrlDecode(), fromDate.UrlDecode(), toDate.UrlDecode(), viewType.UrlDecode());
            ViewData[AppConstants.ViewDataKeys.SEARCH_KEY] = searchModel;
            if (searchModel.HasKeys)
            {
                UtilityDAO dao = new UtilityDAO();
                Wheeler.Domain.DbParameter[] parameters = BuildSearchParameters(searchModel);

                int totalRecord = 0;
                pageNo = pageNo == 0 ? 1 : pageNo;
                DataSet ds = dao.GetPagedData(DbObject.SP.GET_PAGED_TEST_RESULT, parameters, pageNo, ConfigReader.PageSize, out totalRecord, true);

                ViewModels.UtilityModels.PagerConfig pagerConfig = new ViewModels.UtilityModels.PagerConfig(pageNo, ConfigReader.PageSize, totalRecord);
                ListConfig listConfig = new ListConfig(ds.Tables[0], pagerConfig);
                return View(listConfig);
            }
            return View();            
        }
        

        [HttpPost]
        public ActionResult Search(TestResultSearchModel viewModel, int pageNo=0)
        {
            return RedirectToAction("Search", new { RegistrationNo = viewModel.RegistrationNo.UrlEncode(), FromDate = viewModel.FromDate.UrlEncode(), ToDate = viewModel.ToDate.UrlEncode(), ViewType=viewModel.ViewType.UrlEncode(), PageNo = pageNo });
        }

        [HttpPost]
        public String ExportCSV(String registrationNo = null, String fromDate = null, String toDate = null)
        {
            TestResultSearchModel searchModel = new TestResultSearchModel(registrationNo.UrlDecode(), fromDate.UrlDecode(), toDate.UrlDecode(), String.Empty);
            //ViewData[AppConstants.ViewDataKeys.SEARCH_KEY] = searchModel;
            if (searchModel.HasKeys)
            {
                UtilityDAO dao = new UtilityDAO();
                Wheeler.Domain.DbParameter[] parameters = BuildSearchParameters(searchModel);

                int totalRecord = 0;
                DataSet ds = dao.GetPagedData(DbObject.SP.GET_PAGED_TEST_RESULT, parameters, 1, int.MaxValue, out totalRecord, true);
                String fileName = SaveDataTableToDisk(ds.Tables[0]);
                return fileName.UrlEncode();
            }
            return String.Empty;
        }

        public ActionResult DownloadCSV(String file)
        {

            String tempDirectory = Server.MapPath(AppConstants.Directories.TEMP);

            String fileName = System.IO.Path.Combine(tempDirectory, file.UrlDecode());

            ///Files without the temp directory and only *.sql files can be downloaded through this controller
            if (!System.IO.File.Exists(fileName) || System.IO.Path.GetExtension(fileName).ToLower() != ".csv")
                throw new ArgumentException(String.Format("File {0} Cannot be downloaded", file.UrlDecode()));

            ///Intentionally keeping the temp database backup file.
            return File(fileName, "text/plain", System.IO.Path.GetFileName(fileName));

        }

        private string SaveDataTableToDisk(DataTable dt)
        {
            if (dt != null && dt.Rows.Count > 0)
            {
                StringBuilder sb = new StringBuilder(10);
                sb.AppendFormat("Registration No,Engine No,Chassis No,Owner Name,Tested On,Inspection Serial No{0}", Environment.NewLine);
                foreach (DataRow row in dt.Rows)
                {
                    sb.AppendFormat("{0},{1},{2},{3},{4},{5}{6}", 
                        NullHandler.GetString(row["RegistrationNO"]).ToCSV()
                        , NullHandler.GetString(row["EngineNO"]).ToCSV()
                        , NullHandler.GetString(row["ChasisNO"]).ToCSV()
                        , NullHandler.GetString(row["OwnerName"]).ToCSV()
                        , NullHandler.GetDateTime(row["TestPerformedOn"]).ToString(ConfigReader.CSharpCalendarDateFormat)
                        , NullHandler.GetString(row["SerialNumber"]).ToCSV()
                        , Environment.NewLine
                        );
                }
                String fileName = Server.MapPath(AppConstants.Directories.TEMP);
                fileName = System.IO.Path.Combine(fileName, "3WCNGExport.csv");
                System.IO.File.WriteAllText(fileName, sb.ToString());
                return System.IO.Path.GetFileName(fileName);
            }
            return String.Empty;
        }

        public ActionResult PrintResult(int vehicleID)//, int id = 0)
        {
            //TestResult testResult = GetTestResult(id, vehicleID, true);
            List<TestResult> testResults = (from P in _Context.TestResults.Include("Vehicle") where P.VehicleID == vehicleID select P).ToList();
            List<TestResultViewModel> viewModels = Mapper.Map<List<TestResult>, List<TestResultViewModel>>(testResults);
            foreach(TestResultViewModel viewModel in viewModels)
                GetDynamicUI(viewModel, null);

            return View(viewModels);
        }

        public ActionResult Print(int id)
        {
            TestResult entity = _Context.TestResults.Include("Vehicle").Include("ZGL").FirstOrDefault(P => P.ID == id);
            /// DEPRICATED: Implementation for multiple test results for a single vehicle. but had been stopped 
            /// as only successful tests will be kept in the archive.
            //TestResultViewModel model = Mapper.Map<TestResult, TestResultViewModel>(entity);
            //List<TestResultViewModel> viewModels = new List<TestResultViewModel>();
            //viewModels.Add(model);
            //foreach (TestResultViewModel viewModel in viewModels)
            //    GetDynamicUI(viewModel, null);

            TestResultViewModel viewModel = Mapper.Map<TestResult, TestResultViewModel>(entity);
            List<ViewModels.ZGL.Category.ProductGroupProperty> onlyProperties = new List<ViewModels.ZGL.Category.ProductGroupProperty>();
            GetDynamicUI(viewModel, null, onlyProperties);

            ViewData[AppConstants.ViewDataKeys.GENERIC_KEY] = onlyProperties;
            
            //return View("PrintResult", viewModels);
            return View("PrintResult", viewModel);
        }

        #region Image Upload

        public ActionResult PictureList(int vehicleID)
        {
            Wheeler.Domain.Vehicle vehicle = _Context.Vehicles.FirstOrDefault(P => P.ID == vehicleID);            
            VehicleViewModel viewModel = Mapper.Map<Vehicle, VehicleViewModel>(vehicle);
            return View(viewModel);
        }

        [HttpPost]
        public ActionResult PictureList(HttpPostedFileBase vehiclePhoto, int vehicleID)
        {
            Wheeler.Domain.Vehicle vehicle = _Context.Vehicles.FirstOrDefault(P => P.ID == vehicleID);
            //JobSeekerViewModel jobSeekerViewModel = ViewBag.Company = Mapper.Map<Jb.Domain.JobSeeker, JobSeekerViewModel>(vehicle);
            //ViewBag.CompanyID = vehicleID;
            VehicleViewModel viewModel = Mapper.Map<Vehicle, VehicleViewModel>(vehicle);

            if (!WebUtil.IsValidImageFile(vehiclePhoto))
                ViewData[AppConstants.ViewDataKeys.IMAGE_UPLOAD_ERROR] = "Sorry! Your selected file is not a valid Picture file.";
            else
            {
                int w, h;
                String fileName = ImageManager.SaveTempJpeg(vehiclePhoto.InputStream, ConfigReader.VehiclePhotoAspectRatio, out w, out h);
                ViewBag.WidthHeight = String.Format("{0},{1}", w, h);
                ViewBag.CropBoxImageUrl = ImageManager.GetTempImageUrl(fileName);
                ViewData[AppConstants.ViewDataKeys.ORIGINAL_FILE_NAME] = vehiclePhoto.FileName;
            }
            return View(viewModel);
        }

        [HttpPost]
        public ActionResult CropAndSaveImage(VehicleViewModel viewModel)
        {
            cropAndSaveImage(viewModel);
            return Json(viewModel);
        }

        #endregion Image Upload

        [HttpPost]
        public bool ConfirmDataSheet(int id)
        {
            TestResult dataSheet = _Context.TestResults.FirstOrDefault(P => P.ID == id);
            if (dataSheet != null && UserInfo.CanEditTestResult(dataSheet.HasConfirmed, dataSheet.HasPublished))
            {
                dataSheet.HasConfirmed = true;
                dataSheet.ModifiedBy = LoggedInUser.ID;
                dataSheet.ModifiedOn = DateTime.Now;
                _Context.SaveChanges();
                return true;
            }
            return false;
        }

        [HttpPost]
        public bool PublishDataSheet(int id)
        {
            TestResult dataSheet = _Context.TestResults.FirstOrDefault(P => P.ID == id);
            if (dataSheet != null && !dataSheet.HasPublished)
            {
                dataSheet.HasPublished = true;
                dataSheet.ModifiedBy = LoggedInUser.ID;
                dataSheet.ModifiedOn = DateTime.Now;
                _Context.SaveChanges();
                return true;
            }
            return false;
        }

        #endregion Action Methods

        #region Helper Methods

        /// <summary>
        /// Builds a ListConfig object with a list of TestResult
        /// </summary>
        /// <returns></returns>
		private ListConfig BuildTestResultListConfig()
		{
			UtilityDAO dao = new UtilityDAO();
            //Wheeler.Domain.DbParameter[] parameters = new[]{
            //    //new Wheeler.Domain.DbParameter("@VehicleID", LoggedInUser.JobSeekerID)
            //};
            DataSet ds = dao.GetDataSet(DbObject.SP.GET_TESTRESULT_LIST, null, true);
            ListConfig listConfig = new ListConfig(ds.Tables[0], null);
            return listConfig;
		}

        /// <summary>
        /// Gets or builds a TestResult object
        /// </summary>
        /// <param name="id"></param>
        /// <param name="vehicleID"></param>
        /// <returns></returns>
        private TestResult GetTestResult(int id, int vehicleID, bool setFks = true)
        {
            TestResult entity = null;
            Vehicle vehicle = _Context.Vehicles.FirstOrDefault(P => P.ID == vehicleID);
            if (vehicle == null)
                return null;

            if (id == 0)
            {
                entity = _Context.TestResults.FirstOrDefault(P => P.VehicleID == vehicleID);
                if (entity == null)
                {
                    entity = new TestResult();
                    entity.VehicleID = vehicleID;
                }                
                if (setFks)
                {
                    entity.Vehicle = vehicle; //_Context.Vehicles.FirstOrDefault(P => P.ID == vehicleID);
                    entity.ZGL = _Context.ZGLs.FirstOrDefault(P => P.ID == ConfigReader.DefaultZGLID);
                }
                entity.ZGLID = ConfigReader.DefaultZGLID;
                entity.TestStatus = (int)DbObject.TestStatus.NOT_TESTED;
            }
            else
                entity = _Context.TestResults.Include("Vehicle").Include("ZGL").FirstOrDefault(P => P.ID == id && P.VehicleID == vehicleID);

            return entity;
        }

        /// <summary>
        /// Set Dynamic Properties to Save in the Database as XML String
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="dynamicSearchableData">Sets the Dynamic Search Data During Searching Product Properties</param>        
        private void SetDynamicProperties(TestResult entity, ref StringBuilder dynamicSearchableData)
        {
            ZGL objZGL = _Context.ZGLs.FirstOrDefault(P => P.ID == entity.ZGLID);
            if (objZGL != null)
            {
                ///Overridable ZGL
                String ZGL = String.Empty;
                if (!objZGL.PropertyDefinition.IsEmpty())
                    ZGL = objZGL.PropertyDefinition;

                if (!ZGL.IsEmpty()) ///ZGL Exists for this Test
                {
                    Wheeler.Web.ViewModels.ZGL.Category.Category categoryZGL = XmlHelper.ToObject<Wheeler.Web.ViewModels.ZGL.Category.Category>(ZGL);
                    if (categoryZGL == null)
                        entity.DynamicProperties = null;
                    else
                    {
                        ViewModels.ZGL.Product.Product productZGL = new ViewModels.ZGL.Product.Product();
                        productZGL.Property = new List<ViewModels.ZGL.Product.ProductProperty>();
                        foreach (Wheeler.Web.ViewModels.ZGL.Category.ProductGroup group in categoryZGL.Group)
                        {
                            foreach (Wheeler.Web.ViewModels.ZGL.Category.ProductGroupProperty property in group.Property)
                            {
                                ViewModels.ZGL.Product.ProductProperty productProperty = new ViewModels.ZGL.Product.ProductProperty();
                                productProperty.Name = property.Name;
                                productProperty.Value = Request.Form[getDynamicControlName(property.Name)];
                                if (!productProperty.Value.IsEmpty())
                                {
                                    if (property.IsSearchable.IsTrue())
                                        dynamicSearchableData.AppendFormat("{0}{1}", productProperty.Value, Environment.NewLine);

                                    productProperty.Value = productProperty.Value.HtmlEncode();
                                }
                                //property.Value = Request.Form[getDynamicControlName(property.Name)];
                                productZGL.Property.Add(productProperty);
                            }
                        }
                        entity.DynamicProperties = XmlHelper.ToString<Wheeler.Web.ViewModels.ZGL.Product.Product>(productZGL);
                    }
                }
            }
        }

        private String getDynamicControlName(string elementName)
        {
            return String.Format("{0}{1}", AppConstants.UI.DYNAMIC_CONTROL_PREFIX, elementName);
        }


        /// <summary>
        /// Generates the Product Entry Form According to the Selected Categry
        /// </summary>
        /// <param name="testResult"></param>
        /// <param name="zglValues"></param>
        /// <returns></returns>        
        public void GetDynamicUI(TestResultViewModel testResult, String zglValues = null, List<ViewModels.ZGL.Category.ProductGroupProperty> onlyProperties = null)//, int jobID, int categoryID, 
        {
            ZGLViewModel category = testResult.ZGL; 
            if (category != null)
            {
                ///Overridable ZGL
                String ZGL = String.Empty;
                if (!category.PropertyDefinition.IsEmpty())
                    ZGL = category.PropertyDefinition;

                if (!ZGL.IsEmpty())
                {
                    if (!zglValues.IsNullOrEmpty())
                        testResult.DynamicProperties = zglValues.UrlDecode();

                    WebUtil.MapZGL(testResult, ZGL, onlyProperties);
                }
            }            
        }


        private Wheeler.Domain.DbParameter[] BuildSearchParameters(TestResultSearchModel searchModel)
        {         
            searchModel.RegistrationNo = searchModel.RegistrationNo;
            searchModel.ToDate = searchModel.ToDate;
            searchModel.FromDate = searchModel.FromDate;
            List<Wheeler.Domain.DbParameter> parameters = new List<DbParameter>();

            parameters.Add(new Wheeler.Domain.DbParameter("@RegistrationNo", searchModel.RegistrationNo));

            //From Date
            if(searchModel.FromDate.IsEmpty())
                parameters.Add(new Wheeler.Domain.DbParameter("@FromDate", new DateTime(1753, 1, 1)));
            else
                parameters.Add(new Wheeler.Domain.DbParameter("@FromDate", searchModel.FromDate.ToDateTime(ConfigReader.CSharpCalendarDateFormat)));

            //To Date            
            DateTime toDate = DateTime.Now;
            if (searchModel.ToDate.IsEmpty())
                toDate = new DateTime(9999, 12, 31);
            else
            {
                DateTime sDate = searchModel.ToDate.ToDateTime(ConfigReader.CSharpCalendarDateFormat);
                toDate = new DateTime(sDate.Year, sDate.Month, sDate.Day, 23, 59, 59);
            }
            if (searchModel.ToDate.IsEmpty())
                parameters.Add(new Wheeler.Domain.DbParameter("@ToDate", new DateTime(9999, 12, 31)));
            else
                parameters.Add(new Wheeler.Domain.DbParameter("@ToDate", toDate));
            
            //01/01/1753 00:00:00 and 12/31/9999 23:59:59            
            return parameters.ToArray();
        }

        /// <summary>
        /// Crops an image selected by a rectangle and saves it in the filesystem.
        /// </summary>
        /// <param name="viewModel"></param>
        private void cropAndSaveImage(VehicleViewModel viewModel)
        {

            Wheeler.Domain.Vehicle entity = _Context.Vehicles.FirstOrDefault(P => P.ID == viewModel.ID);
            if (entity != null && !viewModel.PictureFile.IsNullOrEmpty())
            {
                String sourceImage = Server.MapPath(viewModel.PictureFile);
                if (System.IO.File.Exists(sourceImage))
                {
                    //Delete Existing Photo from file System, if any
                    if (!entity.PictureFile.IsNullOrEmpty())
                    {
                        String existingPicture = Server.MapPath(ImageManager.GetVehiclePhotoUrl(entity.PictureFile));//, entity.ID));
                        if (System.IO.File.Exists(existingPicture))
                            System.IO.File.Delete(existingPicture);
                    }
                    ///Create the Crop area with user selected rectangle
                    String[] coords = viewModel.CropProperty.Split(',');
                    viewModel.PictureWidth = (int)coords[2].ToFloat();
                    viewModel.PictureHeight = (int)coords[3].ToFloat();
                    Rectangle rectangle = new Rectangle(coords[0].ToInt(), coords[1].ToInt(), viewModel.PictureWidth, viewModel.PictureHeight);

                    String proposedFileName = String.Format("{0}{1}", entity.RegistrationNo, Path.GetExtension(viewModel.OriginalFileName));
                    proposedFileName = Server.MapPath(ImageManager.GetVehiclePhotoUrl(proposedFileName));//, viewModel.ID));
                    //proposedFileName = ImageManager.GetNextFileName(proposedFileName);
                    String[] fileNames = ImageManager.SaveThumbnail(sourceImage, proposedFileName, rectangle, true);//, ImageFor.JobSeeker);

                    ///Delete Original Source Image from the Logo Directory
                    ///Also we can keep this file for future edit but keeping the source will occupy unnecessary space in the
                    ///server, if user doesn't really using it. If need to change then they have to upload a new Image.                        
                    //if (System.IO.File.Exists(fileNames[0]))
                    //    System.IO.File.Delete(fileNames[0]);

                    ///Rename the file
                    if (System.IO.File.Exists(fileNames[1]))
                    {
                        String newFileName = Path.GetFileName(fileNames[1]).Replace("_Thumb", String.Empty);
                        newFileName = Path.Combine(Path.GetDirectoryName(fileNames[1]), newFileName);
                        ///Following delete is necessary as all the uploaded file's name will be same registration number.
                        if (System.IO.File.Exists(newFileName))
                            System.IO.File.Delete(newFileName);

                        System.IO.File.Move(fileNames[1], newFileName);
                        entity.PictureFile = Path.GetFileName(newFileName);
                    }

                    viewModel.PictureFile = ImageManager.GetVehiclePhotoUrl(entity.PictureFile);//, entity.ID);                    

                    _Context.SaveChanges();
                }
            }
        }

        private int GenerateTestRound(int vehicleID)
        {
            var count = (from P in _Context.TestResults where P.VehicleID == vehicleID select P).Count();
            return count + 1;
        }

        #endregion		
    }
}


